const http = require('http');
const Koa = require('koa');
const app = new Koa();
const path = require('path');
const PassThrough = require('stream').PassThrough;

// 静态资源
const static = require('koa-static');

// 用于解析 post 请求中的请求体，存入 ctx.request.body 中
// 支持文件上传
const koaBody = require('koa-body');

// 引入路由模块
const router = require('./routers');

// 用于加密cookie，防止篡改
app.keys = ['today is a good day', 'what is that'];

// test 中间件
app.use(async (ctx, next) => {
  // console.log('ctx.req', ctx.req);
  // console.log('ctx.request', ctx.request);
  ctx.state.user = 'siky';

  // 请求套接字
  // console.log('ctx.request.socket', ctx.socket);


  console.log('1, ctx.request.body', ctx.request.body);


  await next();
  // console.log('ctx.res', ctx.res);
  // console.log('ctx.response', ctx.response);

  // 断言，判断是否有 user， 如果有就不执行，如果没有就报错401并返回信息
  ctx.assert(ctx.state.user, 401, 'User not found. Please login!');

  // 套接字
  // console.log('ctx.response.socket', ctx.response.socket)

  // 缓存设置
  ctx.set('Cache-Control', 'max-age=31536000');
})

// ctx 未经过 koaBody 中间件的时候，没有 ctx.request.body ，经过 koaBody 之后会加上
// 加上 multipart 用于支持文件上传
app.use(koaBody({multipart: true}));

// test 中间件2
app.use(async (ctx, next) => {
  console.log('2, ctx.request.body', ctx.request.body);
  await next();
})

// logger 中间件
app.use(async (ctx, next) => {
  await next();
  let responseTime = ctx.response.get('X-Response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${responseTime}`);
  ctx.assert(ctx.state.user, 401, 'User not found. Please login!');
})

// 响应时间中间件
app.use(async (ctx, next) => {
  let start = Date.now();
  await next();
  let ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
  console.log('ctx.state.user', ctx.state.user);
})

app.use(async (ctx, next) => {
  await next();
  console.log('cookie - account', ctx.cookies.get('account'))
  console.log('cookie - name', ctx.cookies.get('name'))
  ctx.cookies.set('account', 'sikybest', {
    signed: true,
    maxAge: 1000,
    // domain: 'baidu.com',
    // secure: true,
    sameSite: 'lax',
  });
  ctx.cookies.set('name', 'bellayang', {
    signed: true,
    expires: new Date('Wed, 21 Oct 2022 07:28:00 GMT'),
  });
})

// 静态资源服务器
app.use(
  static(path.join(__dirname + '/public'), {
    maxage: 18000
  })
);

// EventSource 是一种连接后，服务端可以给web客户端推送消息的 api
app.use(async (ctx, next) => {
  if (ctx.request.url === '/event-source') {
    const content = 'EventSource 是一种连接后，服务端可以给web客户端推送消息的 api 。EventSource 是一种连接后，服务端可以给web客户端推送消息的 api 。EventSource 是一种连接后，服务端可以给web客户端推送消息的 api 。EventSource 是一种连接后，服务端可以给web客户端推送消息的 api 。';
    const stream = new PassThrough();

    ctx.set({
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      // 保持连接
      'Connection': 'keep-alive',
      // 允许跨域
      'Access-Control-Allow-Origin': '*',
    });
    ctx.status = 200;
    ctx.body = stream;

    let index = 0;
    setInterval(() => {
      const s = content[index];
      if (s) {
        stream.write(`data: ${s}\n\n`);
        index++;
      } else {
        stream.write(`data: end\n\n`);
      }
    }, 100);
  } else {
    await next();
  }
});

// 配置路由项
app.use(router.routes());

// app.use(async ctx => {
//   ctx.body = '<h2>Hello Koa!!!!</h2>';
//   ctx.message = 'very ok!';
//   // ctx.throw(401, 'access_denied', { user: 'siky' })
// })

app.listen(4001, () => {
  console.log('>>> Server Listen In: http://localhost:' + 4001);
});

/**
 * 关于存储，一般都会有几个属性
 * name/key   名称
 * value      值
 * max-age    有效时长（有效秒数）
 * expire     失效时间（具体时间）
 */
